﻿#include "CmdAnalysis.h"
#include <QMessageBox>
#include <ThreadMsgManager.h>


/*
.\BackPath.exe D:\backup  -fileterSuffix .bak -outparam -form "%fileName% %changeDateTime%"   -addSecond 1 -formDateTime yyyy-MM-dd >b.txt
*/
void CmdAnalysis::anasyParameter(int& argc
	, char** argv) {
	parameter = initParameters(argc, argv, currentExeName);
	if( parameter.contains(debugOutOption) ) {
		for( auto iterator = parameter.begin( ), end = parameter.end( );iterator != end;++iterator ) {
			QString buff;
			QVector<QString>& vector = iterator.value( );
			for( int index = 0;index < vector.size( );++index )
				buff.append(vector.at(index)).append("\n\t");
			std::cout << "key : \n\t" << iterator.key( ).toLocal8Bit( ).constData( ) << "\nValue : \n\t" << buff.toLocal8Bit( ).constData( ) << std::endl;
		}
	}
}

CmdAnalysis::CmdAnalysis(int& argc
	, char** argv
	, int i): QApplication{ argc,argv,i } {
	anasyParameter(argc, argv);
}

int CmdAnalysis::appRun( ) {

	// 帮助文档
	if( parameter.contains("-h") || parameter.contains("-help") || parameter.contains("-?") ) {
		QString helpOutStr;
		helpOutStr.sprintf("支持\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\n\t\t%s\n\t%s\n\t\n\t\t%s\n\t%s\n\t\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n\t%s 或 %s\n\t\t%s\n\t%s\n\t\t%s\n==\n", setChangeTimeSparationOption, setChangeTimeSparationOptionHelp, setChangeDataSparationOption, setChangeDataSparationOptionHelp, setChangeTimeOption, setChangeTimeOptionHelp, setChangeDateOption, setChangeDateOptionHelp, addYearOption, addYearOptionHelp, addMonthOtion, addMonthOtionHelp, addDayOption, addDayOptionHelp, addHourOption, addHourOptionHelp, addMinuteOption, addMinuteOptionHelp, addMsecOption, addMsecOptionHelp, formOption, formOptionHelp, formDateTimeOption, formDateTimeOptionHelp, fileterSuffixOption, fileterSuffixOptionHelp, filterOption, filterOptionHelp, filterSparationOption, filterSparationOptionHelp, regExpOption, regExpOptionHelp, regExpSparationOption, regExpSparationOptionHelp, copyDestOption, copyDestPathOptionHelp, moveDestOption, moveDestOptionHelp, creatorPathOption, mkPathOption, creatorPathOptionHelp, debugOutOption, debugOutOptionHelp);
		std::cout << helpOutStr.toLocal8Bit( ).constData( ) << std::endl;
	}
	if( parameter.contains(creatorPathOption) ) {
		const QVector<QString> vector = parameter.value(creatorPathOption);
		QDir dir;
		for( auto mkPath : vector ) {
			QFileInfo info(mkPath);
			auto&& targetPath = info.absoluteFilePath( );
			if( !dir.mkpath(targetPath) )
				std::cout << targetPath.append("\t 创建失败").toLocal8Bit( ).constData( ) << std::endl;
			else
				std::cout << targetPath.append("\t 创建成功").toLocal8Bit( ).constData( ) << std::endl;
		}
	}
	if( parameter.contains(mkPathOption) ) {
		const QVector<QString> vector = parameter.value(mkPathOption);
		QDir dir;
		for( auto mkPath : vector ) {
			QFileInfo info(mkPath);
			QString targetPath = info.absoluteFilePath( );
			if( !dir.mkpath(targetPath) )
				std::cout << targetPath.append("\t 创建失败").toLocal8Bit( ).constData( ) << std::endl;
			else
				std::cout << targetPath.append("\t 创建成功").toLocal8Bit( ).constData( ) << std::endl;
		}
	}
	// 其他选项匹配
	if( parameter.contains(mkPathOption) ) {
		// 创建目录
		const QVector<QString> charses = parameter.value(mkPathOption);
		QDir dir;
		for( auto& path : charses ) {
			QFileInfo info(path);
			QString absoluteFilePath = info.absoluteFilePath( );
			dir.mkpath(absoluteFilePath);
		}
	}
	if( parameter.contains(moveDestOption) ) {
		fileOpterator = 1;
		// 移动到目标
		const QVector<QString> charses = parameter.value(moveDestOption);
		for( auto& path : charses ) {
			QFileInfo info(path);
			if( info.exists( ) && info.isDir( ) )
				destPtahVector.append(info.absoluteFilePath( ));
		}
	}
	if( parameter.contains(copyDestOption) ) {
		if( fileOpterator != 1 ) {
			// 复制到目标
			const QVector<QString> charses = parameter.value(copyDestOption);
			for( auto& path : charses ) {
				QFileInfo info(path);
				if( info.exists( ) && info.isDir( ) )
					destPtahVector.append(info.absoluteFilePath( ));
			}
			fileOpterator = 2;
		}
	}
	if( parameter.contains(setChangeTimeSparationOption) ) {
		// 时间分隔符
		addTimeSparation = parameter.value(setChangeTimeSparationOption)[0];
	}
	if( parameter.contains(setChangeDataSparationOption) ) {
		// 日期分隔符
		addDataSparation = parameter.value(setChangeDataSparationOption)[0];
	}
	if( parameter.contains(setChangeTimeOption) ) {
		// 加上时间
		auto&& values = parameter.value(setChangeTimeOption);
		QString target;
		for( auto& paramt : values )
			target.append(paramt).append(addTimeSparation);
		QStringList list = target.split(addTimeSparation);
		for( int index = 0;index < list.size( );++index ) {
			const QString string = list.at(index);
			if( !string.isEmpty( ) ) {
				bool isOk = false;
				int toInt = string.toInt(&isOk);
				if( isOk ) {
					if( index == 0 )
						setCompleterTimeHour(toInt);
					else if( index == 1 )
						setCompleterTimeMinute(toInt);
					else if( index == 2 )
						setCompleterTimeSecond(toInt);
					else if( index == 3 )
						setCompleterTimeMsec(toInt);
				}
			}
		}
	}
	if( parameter.contains(setChangeDateOption) ) {
		// 加上日期
		auto&& values = parameter.value(setChangeDateOption);
		QString target;
		for( auto& paramt : values )
			target.append(paramt).append(addTimeSparation);
		QStringList list = target.split(addTimeSparation);
		for( int index = 0;index < list.size( );++index ) {
			const QString string = list.at(index);
			if( !string.isEmpty( ) ) {
				bool isOk = false;
				int toInt = string.toInt(&isOk);
				if( isOk ) {
					if( index == 0 )
						setCompleterDateYear(toInt);
					else if( index == 1 )
						setCompleterDateMonth(toInt);
					else if( index == 2 )
						setCompleterDateDay(toInt);
				}
			}
		}
	}
	if( parameter.contains(addYearOption) ) {
		// 添加年份
		QString day = parameter.value(addYearOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterDateYear(toInt);
	}
	if( parameter.contains(addMonthOtion) ) {
		// 添加月份
		QString day = parameter.value(addMonthOtion)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterDateMonth(toInt);
	}
	if( parameter.contains(addDayOption) ) {
		// 添加天数
		QString day = parameter.value(addDayOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterDateDay(toInt);
	}
	if( parameter.contains(addHourOption) ) {
		// 添加小时
		QString day = parameter.value(addHourOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterTimeHour(toInt);
	}
	if( parameter.contains(addMinuteOption) ) {
		// 添加分钟
		QString day = parameter.value(addMinuteOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterTimeMinute(toInt);
	}
	if( parameter.contains(addSecondOption) ) {
		// 添加秒数
		QString day = parameter.value(addSecondOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterTimeSecond(toInt);
	}
	if( parameter.contains(addMsecOption) ) {
		// 添加毫秒
		QString day = parameter.value(addMsecOption)[0];
		bool isOk = false;
		int toInt = day.toInt(&isOk);
		if( isOk )
			addCompleterTimeMsec(toInt);
	}
	if( parameter.contains(formOption) ) {
		const QString chars = parameter.value(formOption)[0];
		// 设置一般格式化
		setFileOutForm(chars);
	}
	if( parameter.contains(formDateTimeOption) ) {
		// 设置时间格式化
		const QVector<QString>&& strings = parameter.value(formDateTimeOption);
		QString over;
		for( auto& stri : strings )
			over.append(stri).append(' ');
		setFileOutDateTimeForm(over);
	}
	if( parameter.contains(fileterSuffixOption) ) {
		// 设置尾过滤
		setNormalFilter("*" + parameter.value(fileterSuffixOption)[0]);
	}
	if( parameter.contains(filterOption) ) {
		if( parameter.contains(filterSparationOption) ) {
			// 一般间接符
			normalFilterAppendVector = parameter.value(filterSparationOption);
		}
		// 设置一般过滤
		const QVector<QString>&& strings = parameter.value(filterOption);
		QString over;
		int length = normalFilterAppendVector.size( );
		for( int index = 0, appVectorIndex = 0;index < strings.size( );++index ) {
			if( length != 0 ) {
				if( index < length )
					appVectorIndex = index;
				over.append(strings.at(index)).append(normalFilterAppendVector.at(appVectorIndex));
			} else
				over.append(strings.at(index)).append(' ');
		}
		setNormalFilter(over);
	}
	if( parameter.contains(regExpOption) ) {
		if( parameter.contains(regExpSparationOption) ) {
			// 设置正则间接符
			regExpAppendVector = parameter.value(regExpSparationOption);
		}
		// 设置正则
		const QVector<QString>&& strings = parameter.value(regExpOption);
		QString over;
		int length = regExpAppendVector.size( );
		for( int index = 0, appVectorIndex = 0;index < strings.size( );++index ) {
			if( length != 0 ) {
				if( index < length )
					appVectorIndex = index;
				over.append(strings.at(index)).append(regExpAppendVector.at(appVectorIndex));
			} else
				over.append(strings.at(index)).append(' ');
		}
		setRegExpFilter(over);
	}
	// 命令行输出
	const QVector<QString> vector = parameter.value(currentExeName);
	if( !vector.isEmpty( ) ) {
		QVector<QString>::const_iterator begin = vector.begin( );
		auto&& end = vector.end( );
		for( ;begin != end;++begin ) {
			ThreadShowChangeFiles* findChangeFiles = new ThreadShowChangeFiles;
			threadVectorAppendObj(findChangeFiles);
			connect(findChangeFiles, &ThreadShowChangeFiles::overTask, this, &CmdAnalysis::showChangeFilesInfo);
			findChangeFiles->setSrcFilePath(*begin);
			findChangeFiles->start( );
		}
	}
	if( !releaseObj( ) )
		exec( );
	return 0;
}


//doFileOutForm(const QString& filePath)

CmdAnalysis::~CmdAnalysis( ) {}

void CmdAnalysis::showChangeFilesInfo(QHash<QString, QDateTime>* fileChangeInfo
	, QString* fileParh) {
	ThreadMsgManager* threadMsgManager = new ThreadMsgManager(*fileChangeInfo, *fileParh);
	threadVectorAppendObj(threadMsgManager);
	connect(threadMsgManager, &ThreadMsgManager::releaseEmit, this, &CmdAnalysis::realeaseThread);
	threadMsgManager->start( );
	// 文件拷贝或移动

	QHash<QString, QDateTime>::iterator iterator = fileChangeInfo->begin( );
	QHash<QString, QDateTime>::iterator end = fileChangeInfo->end( );
	// 配置输出格式

	QStringList outLogStrList;
	QList<QFuture<QStringList>> futures;
	for( ;iterator != end;++iterator ) {
		QString key = iterator.key( );
		//copyOrMoveFiles(fileParh, key, copyStr, moveStr);

		futures.append(QtConcurrent::run(doFiles, fileParh, key, fileOpterator, &destPtahVector));
	}
	for( auto& futareTask : futures ) {
		futareTask.waitForFinished( );
		outLogStrList << futareTask.result( ).join("");
	}
	if( !fileOpterator ) {
		QFile copyOutLog(QDir::currentPath( ) + "/copy.log");
		auto&& open = copyOutLog.open(QIODevice::WriteOnly | QIODevice::Text);
		if( open ) {
			copyOutLog.write(outLogStrList.join("\n").toUtf8( ));
		}
	} else if( fileOpterator == 1 ) {
		QFile moveOutLog(QDir::currentPath( ) + "/move.log");
		auto&& open = moveOutLog.open(QIODevice::WriteOnly | QIODevice::Text);
		if( open ) {
			moveOutLog.write(outLogStrList.join("\n").toUtf8( ));
		}
	}

	// 释放
	QObject* object = sender( );
	delete object;
	// 释放
	releaseObj(object);
}

// 是否存在完全释放
// 已经完全释放返回 true
// 还存在则返回 false
bool CmdAnalysis::releaseObj(QObject* obj) {
	if( threadVectorReleaseObj(obj) ) {
		quit( );
	} else
		return false;
	return true;
}

void CmdAnalysis::realeaseThread(QThread* obj) {
	obj->quit( );
	delete obj;
	// 释放
	releaseObj(obj);
}
